home *** CD-ROM | disk | FTP | other *** search
- /*
- SBR_C - QL-Kermit general subroutines
-
- Extracts from ck*.c files, (C) Columbia University
- */
-
-
- /* Include files */
-
- #include "ram1_ker_h" /* Kermit definitions */
-
- #include "flp1_fcntl_h" /* File opening modes */
- #include "flp1_ctype_h" /* Character test macros */
-
-
- /* External variables */
-
- extern int state; /* Current switcher state */
- extern int ttychid; /* QDOS channel ID of comms line */
- extern int tvalue; /* Receive timeout (frames) */
- extern int debug; /* Debugging level */
- extern int serno; /* Serial port in use */
- extern int parity; /* Parity setting */
- extern int speed; /* Baud rate */
- extern int ttyfd; /* FD of communication line */
- extern int trans; /* File name translation */
- extern int tlevel; /* TAKE file nesting level */
-
- extern int _oserr; /* QDOS error code */
- extern int oserr; /* Copy of above */
-
- extern bool timer; /* Timer enabled flag */
- extern bool cxseen,czseen; /* Transfer interrupt flags */
- extern bool local; /* Operation mode flag */
- extern bool keep; /* Incomplete file flag */
-
- extern char *newfilnam; /* Transfer file name */
- extern char *errdata; /* Data for E packet */
- extern char *suffix; /* Outgoing file suffix */
-
- extern char ttyname[]; /* Name of communication line */
-
- extern int fp; /* Transfer file */
-
- extern FILE *tfile[MAXTAKE]; /* TAKE file stack */
-
-
- /* External functions */
-
- char *strchr(); /* Find first character */
- char *strrchr(); /* Find last character */
-
-
- /* Local variables */
-
- static char buf[BLKSIZ]; /* Transfer file buffer */
- static int bufp; /* Index into above */
- static int n; /* Character count */
-
-
- /* DELCH - Special QL console character delete */
-
- delch()
- {
- sd_pcol(fgetchid(stdout),1);
- putchar(' ');
- sd_pcol(fgetchid(stdout),1);
- }
-
-
- /* TREAD - Read a character from line, with timeout */
-
- int tread()
- {
- unsigned char t;
- int e;
- int w = 0;
-
- do
- {
- if (!io_pend(ttychid,1)) /* Check for pending input */
- {
- io_fbyte(ttychid,0,&t); /* If a byte available, */
- if (parity!=PYNONE) t &= 0177; /* remove parity */
- return((int) t); /* and return immediately */
- }
- w++; /* otherwise continue */
- } while ((e = chkint())>=0 &&
- (w<tvalue || !timer)); /* until timeout or interrupt */
- if (e==INTE) return(e); /* ^E interrupt */
- if (debon) printf("Receiver timeout\n");
- return(BAD); /* Timeout */
- }
-
-
- /* CHKINT - Check for console interrupts */
-
- int chkint()
- {
- unsigned char ch;
-
- if (!io_pend(fgetchid(stdin),0))
- {
- io_fbyte(fgetchid(stdin),0,&ch); /* If a key pressed, read it */
- switch (ch)
- {
-
- case 'B'-'@': /* CTRL-B */
- case 'Z'-'@': /* CTRL-Z */
- if (state==S_DATA || state==R_DATA)
- {
- intrpt("Batch aborted");
- czseen = TRUE;
- }
- endcase;
-
- case 'F'-'@': /* CTRL-F */
- case 'X'-'@': /* CTRL-X */
- if (state==S_DATA || state==R_DATA)
- {
- intrpt("File aborted");
- cxseen = TRUE;
- }
- endcase;
-
- case 'E'-'@': return(INTE); /* CTRL-E */
-
- case 'T'-'@': intrpt("Forced timeout"); /* ENTER */
- return(BAD);
-
- }
- }
- return(0);
- }
-
-
- /* FLUSHINPUT - Dump all pending input to clear stacked up NAKs */
-
- flushinput()
- {
- char dump;
-
- if (debon) printf("Flushing input on %s\n",ttyname);
- while (io_pend(ttychid,1)==0) io_fbyte(ttychid,0,&dump);
- if (debon) printf("Input flushed\n");
- }
-
-
- /* ERROR - Print an error message */
-
- error(fmt,a1,a2,a3,a4,a5)
- char *fmt;
- {
- printf("ERROR: ");
- printf(fmt,a1,a2,a3,a4,a5);
- printf("\n");
- }
-
-
- /* PRERRPKT - Print contents of error packet received from remote host */
-
- prerrpkt(msg)
- char *msg;
- {
- printf("REMOTE ERROR: %s\n",msg);
- }
-
-
- /* INTRPT - Print a transfer interruption message */
-
- intrpt(msg)
- char *msg;
- {
- printf("INTERRUPT: %s\n",msg);
- }
-
-
- /* STNAME - return a printable state name */
-
- char *stname(st)
- int st;
- {
- switch(st)
- {
-
- case ABORT: return("ABORT");
- case COMP: return("COMPLETE");
- case IDLE: return("IDLE");
- case R_INIT: return("REC_INIT");
- case R_FILE: return("REC_FILE");
- case R_DATA: return("REC_DATA");
- case S_INIT: return("SEND_INIT");
- case S_FILE: return("SEND_FILE");
- case S_DATA: return("SEND_DATA");
- case S_EOF: return("SEND_EOF");
- case S_BRK: return("SEND_EOT");
- case S_COMD: return("SEND_SERVER_CMD");
- case G_INIT: return("SEND_SERVER_INIT");
- case K_ERR: return("SEND_ERROR");
- default: return("UNKNOWN");
-
- }
- }
-
-
- /* RTLIM - Retry limit exceeded */
-
- int rtlim()
- {
- strcpy(errdata,"Retry limit exceeded");
- error(errdata);
- return(K_ERR);
- }
-
-
- /* INTERRUPT - CTRL-E pressed to cause error abort */
-
- int interrupt()
- {
- strcpy(errdata,"CTRL-E interrupt");
- intrpt("Transaction aborted");
- return(K_ERR);
- }
-
-
- /* ERRSTR - give a description for a QDOS error */
-
- char *errstr(code)
- int code;
- {
- switch (-code)
- {
-
- case 0: return("No error");
- case 1: return("Not complete");
- case 2: return("Invalid job");
- case 3: return("Out of memory");
- case 4: return("Out of range");
- case 5: return("Buffer full");
- case 6: return("Channel not found");
- case 7: return("Not found");
- case 8: return("Already exists");
- case 9: return("In use");
- case 10: return("End of file");
- case 11: return("Drive full");
- case 12: return("Bad name");
- case 13: return("Transmit error");
- case 14: return("Format failed");
- case 15: return("Bad parameter");
- case 16: return("Bad medium");
- case 17: return("Error in expression");
- case 18: return("Overflow");
- case 19: return("Not implemented");
- case 20: return("Read only");
- case 21: return("Bad line");
- default: return("Unknown error");
-
- }
- }
-
-
- /* QDOSERR - An error from QDOS encountered */
-
- int qdoserr()
- {
- strcpy(errdata,errstr(oserr));
- printf("QDOS: %s\n",errdata);
- return(K_ERR);
- }
-
-
- /* CLOSEF - Close transfer file if open */
-
- closef()
- {
- if (fp>=0) close(fp); /* File open? */
- fp = -1;
- }
-
-
- /* TFGET - Get a character from transfer file (from K&R - MCC library
- getchar() gives EOF if the file contains more than one $FF byte
- in succession!)
- */
-
- int tfget()
- {
- if (n==0) /* Buffer empty? */
- {
- n = read(fp,buf,BLKSIZ); /* Read data */
- bufp = 0; /* and restore pointer */
- }
-
- return((--n>=0) ? buf[bufp++]&0377 : EOF); /* Return data or EOF indication */
- }
-
-
- /* DEVOPEN - open transfer file, using appropriate device if necessary */
-
- int devopen(name,dev,mode)
- char *name,*dev;
- int mode;
- {
- strcpy(newfilnam,name); /* Name for first try */
- if ((fp = open(newfilnam,mode))<0)
- {
- oserr = _oserr;
- if (debon) printf("Open %s failed\n",newfilnam);
- if (oserr==ERR_NF) /* Maybe device name left off */
- {
- strcpy(newfilnam,dev); /* Add device name */
- strcat(newfilnam,name); /* to given name */
- if ((fp = open(newfilnam,mode))<0)
- {
- oserr = _oserr;
- if (debon) printf("Open %s failed\n",newfilnam);
- }
- }
- }
-
- n = bufp = 0; /* Initialise read pointers */
- return(fp);
- }
-
-
- /* CLS - clear a window */
-
- cls(chan)
- char *chan;
- {
- struct REGS in,out;
-
- in.D0 = 0x20; /* SD.CLEAR */
- in.D3 = -1; /* Timeout */
- in.A0 = chan; /* Channel */
-
- QDOS3(&in,&out);
- }
-
-
- /* SETBAUD - Set the communication line baud rate */
-
- setbaud(speed)
- int speed;
- {
- struct REGS in,out;
-
- in.D0 = 0x12; /* MT.BAUD */
- in.D1 = (short) speed; /* Baud rate */
-
- if (QDOS1(&in,&out)==0) return(speed);
- else return(-1);
- }
-
-
- /* WAIT - Delay for d seconds, or until a key pressed */
-
- wait(d)
- int d;
- {
- int i;
-
- for (i = 0; i<d && (io_pend(fgetchid(stdin),0)!=0); i++) mt_susjb(1*50);
- }
-
-
- /* MT_SUSJB - Sleep this job for w frames (1/50s) */
-
- mt_susjb(w)
- int w;
- {
- struct REGS in,out;
-
- in.D0 = 0x08; /* MT.SUSJB */
- in.D1 = -1; /* Current job */
- in.D3 = (short) w; /* Timeout */
- in.A1 = 0; /* No flag byte */
-
- QDOS1(&in,&out);
- }
-
-
- /* PTYPE - return a string for parity type p */
-
- char *ptype(p)
- int p;
- {
- switch(p)
- {
-
- case PYNONE: return("none");
- case PYEVEN: return("even");
- case PYODD: return("odd");
- case PYMARK: return("mark");
- case PYSPC: return("space");
- default: return("UNKNOWN");
-
- }
- }
-
-
- /* MKTTNAM - build a name to open the serial port with */
-
- int mkttnam(line,pty)
- int line,pty;
- {
- int i;
-
- strcpy(ttyname,"ser"); /* First part of name */
- i = strlen(ttyname);
-
- ttyname[i++] = line+'0'; /* Port number */
-
- switch (pty) /* Parity setting */
- {
- case PYEVEN: ttyname[i++] = 'e'; endcase;
- case PYODD: ttyname[i++] = 'o'; endcase;
- case PYMARK: ttyname[i++] = 'm'; endcase;
- case PYSPC: ttyname[i++] = 's'; endcase;
- }
-
- ttyname[i++] = 'h'; /* Use handshake */
- ttyname[i++] = 'r'; /* Raw data */
- ttyname[i] = '\0'; /* Terminate the string */
- return(i); /* and return the length */
- }
-
-
- /* NEWTTY - re-open a serial port with the current settings */
-
- int newtty()
- {
- if (ttyfd>0)
- {
- close(ttyfd); /* Close old line if open */
- if (debon) printf("Closed %s\n",ttyname);
- ttyfd = -1;
- }
-
- ttyname[0] = '\0'; /* and clear out name */
- local = FALSE; /* and status */
-
- if (serno>0) /* New line to be opened? */
- {
- mkttnam(serno,parity); /* Make new name */
- ttyfd = open(ttyname,O_RDWR); /* Open line */
- if (ttyfd<0) /* Open failed? */
- {
- oserr = _oserr; /* Save QDOS error code */
- error("Cannot open %s",ttyname); /* Print error messages */
- qdoserr();
- speed = -1; /* Unset line parameters */
- return(-2);
- }
- local = TRUE; /* Set local/remote status */
- ttychid = (int) getchid(ttyfd); /* Reset channel ID */
- if (debon) printf("Opened %s\n",ttyname);
- }
- else speed = -1; /* Remote mode, unset speed */
-
- return(0);
- }
-
-
- /* DISCARD - delete an incomplete file, if appropriate flag set */
-
- discard(fn)
- char *fn;
- {
- if (!keep)
- {
- unlink(fn);
- printf("Discarded %s\n",fn);
- }
- }
-
-
- /* CHKQUOTE - Check for a valid quote character */
-
- bool chkquote(c)
- char c;
- {
- return((c>' ' && c<'@') || (c>'a' && c<DEL));
- }
-
-
- /* NAMEPATCH - change our job name from "C-PROG" to something sensible */
-
- namepatch()
- {
- char *p; /* Destination pointer */
- char *s = "Kermit"; /* New job name */
- struct REGS in,out;
-
- in.D0 = 0; /* MT.INF */
- QDOS1(&in,&out); /* Get our job ID */
-
- in.D0 = 2; /* MT.JINF */
- in.D1 = out.D1; /* Job ID */
- in.D2 = 0; /* Parent ID */
- QDOS1(&in,&out); /* Get our base address */
-
- p = out.A0+8; /* Point to job name length */
- if (*((short *) p)==6) /* Check it */
- {
- p += 2;
- while (*s!='\0') *p++ = *s++; /* and copy in new one */
- }
- }
-
-
- /* RTOL - convert a filename from Kermit- to QL-format: (a) change '.'s
- to '_'s, (b) make letters lower case
- */
-
- rtol(new,old)
- char new[],old[];
- {
- int i;
- char c;
-
- if (trans==FNUNTR) strcpy(new,old); /* Literal mode , don't convert */
- else
- {
- for (i = 0; (c = old[i])!='\0'; i++)
- {
- if (c=='.') new[i] = '_';
- else if (isupper(c)) new[i] = tolower(c);
- else new[i] = c;
- }
- new[i] = '\0';
- }
-
- if (debon) printf("rtol: converted %s to %s\n",old,new);
-
- }
-
-
- /* LTOR - convert a filename from QL- to Kermit-format: (a) remove first
- component (device name), (b) change last '_' to '.', (c) make letters
- upper case. We know that old[] has at least 2 components here (the QL
- device name and the file name).
- */
-
- ltor(new,old)
- char new[],old[];
- {
- int l,s,j;
- char c;
- char wrk[30];
-
- if (trans==FNUNTR) strcpy(new,old); /* Literal mode, don't convert */
- else
- {
- strcpy(wrk,old); /* Take local copy of name */
- if (strlen(suffix)>0) /* Suffix to be added? */
- {
- strcat(wrk,"_"); /* Yes, add seperator */
- strcat(wrk,suffix); /* then the suffix */
- }
-
- s = (int) (strchr(wrk,'_')-wrk+1); /* Find start of 2nd component */
- l = (int) (strrchr(wrk,'_')-wrk); /* and last underscore */
-
- for (j = 0; (c = wrk[s])!='\0'; s++,j++)
- {
- if (s==l) new[j] = '.';
- else if (islower(c)) new[j] = toupper(c);
- else new[j] = c;
- }
- new[j] = '\0';
- }
-
- if (debon) printf("ltor: converted %s to %s\n",old,new);
-
- }
-
-
- /* TCLOSE - close the current TAKE file */
-
- tclose()
- {
- fclose(tfile[tlevel--]);
- if (debon) printf("TAKE file level %d closed\n",tlevel+1);
- }
-